home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ROADS15.ARJ
/
INITROAD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-15
|
15KB
|
468 lines
#define INITROAD_C
#include <stdlib.h>
#include <time.h>
#include <fastgraf.h>
#include "roads.h"
#include "tiles.h"
extern int far *topography; /* BACKGROUND TILE LIST (ARRAY) */
extern int far *terrain; /* FOREGROUND TILE LIST (ARRAY) */
/* FOR AI - NUMBER OF ROADS TO PLACE ON SCREEN */
#define MAX_ROADS ((WORLD_WIDTH+WORLD_HEIGHT)/2)
#define MIN_ROADS ((WORLD_WIDTH+WORLD_HEIGHT)/8)
#define CHANCE_CROSSROAD 75 /* 3/4 CHANCE OF A CROSSROAD VS T */
/* DIRECTIONS */
#define NUM_DIRECTIONS 4
#define FIRST_DIRECTION 1
#define DIRECTION_UP 1
#define DIRECTION_DOWN 2
#define DIRECTION_LEFT 3
#define DIRECTION_RIGHT 4
#define ROAD_LEADERS 12 /* USED IN CREATE_ROADS */
/*
*
* Randomly creates roads and places them in the foreground tile list.
* This function overwrites other non-road foreground tiles.
* (To prevent this, call this function first.)
*
*/
void create_roads (void)
{
int entry, keepgoing=TRUE, direction, chance;
int x,y,nextx,nexty; /* LOCATION OF CURRENTLY PLACED ROAD TILE */
int roads_left; /* NUMBER OF COMPLETE ROADS LEFT TO PLACE */
int failed_roads=0;
int current_tile;
/* ROADS ARE PICKED FROM THESE LISTS -- INCREASE ROAD_LEADERS */
/* AND ADD ROAD TILES TO THESE LISTS TO INCREASE CHANCE OF */
/* SPECIFIED ROADS BEING PLACED */
int roads_to_right [ROAD_LEADERS] = { ROAD_H, ROAD_H, ROAD_UR, ROAD_DR,
ROAD_H, ROAD_H, ROAD_H, ROAD_H,
ROAD_H, ROAD_H, ROAD_H, ROAD_H, };
int roads_to_left [ROAD_LEADERS] = { ROAD_H, ROAD_H, ROAD_UL, ROAD_DL,
ROAD_H, ROAD_H, ROAD_H, ROAD_H,
ROAD_H, ROAD_H, ROAD_H, ROAD_H, };
int roads_to_down [ROAD_LEADERS] = { ROAD_V, ROAD_V, ROAD_UL, ROAD_UR,
ROAD_V, ROAD_V, ROAD_V, ROAD_V,
ROAD_V, ROAD_V, ROAD_V, ROAD_V, };
int roads_to_up [ROAD_LEADERS] = { ROAD_V, ROAD_V, ROAD_DL, ROAD_DR,
ROAD_V, ROAD_V, ROAD_V, ROAD_V,
ROAD_V, ROAD_V, ROAD_V, ROAD_V, };
roads_left=random (MAX_ROADS-MIN_ROADS)+MIN_ROADS;
/************************************************\
* PLACE FIRST TILE AT WORLD SCREEN EDGE *
\************************************************/
while (roads_left-- && failed_roads<=MAX_FAILS)
{
/* PICK RANDOM ENTRY POINT */
keepgoing=TRUE;
entry=random(NUM_DIRECTIONS)+FIRST_DIRECTION;
switch (entry)
{
/********/ case DIRECTION_UP: /* TOP ENTRY */
x=random(WORLD_WIDTH); y=0;
current_tile=terrain[WORLD_TILE(x,y)];
if (!isroad(current_tile))
{
current_tile=terrain[WORLD_TILE(x,y)]=
roads_to_up[random(ROAD_LEADERS)];
direction=roadexit(current_tile, DIRECTION_DOWN);
break;
}
else
{
roads_left++;
failed_roads++;
keepgoing=FALSE;
break;
}
/********/ case DIRECTION_DOWN: /* BOTTOM ENTRY */
x=random(WORLD_WIDTH); y=WORLD_HEIGHT-1;
current_tile=terrain[WORLD_TILE(x,y)];
if (!isroad(current_tile))
{
current_tile=terrain[WORLD_TILE(x,y)]=
roads_to_down[random(ROAD_LEADERS)];
direction=roadexit(current_tile, DIRECTION_UP);
}
else
{
roads_left++;
failed_roads++;
keepgoing=FALSE;
}
break;
/********/ case DIRECTION_LEFT: /* LEFT ENTRY */
x=0; y=random(WORLD_HEIGHT);
current_tile=terrain[WORLD_TILE(x,y)];
if (!isroad(current_tile))
{
current_tile=terrain[WORLD_TILE(x,y)]=
roads_to_left[random(ROAD_LEADERS)];
direction=roadexit(current_tile, DIRECTION_RIGHT);
}
else
{
roads_left++;
failed_roads++;
keepgoing=FALSE;
}
break;
/********/ case DIRECTION_RIGHT: /* RIGHT ENTRY */
x=WORLD_WIDTH-1; y=random(WORLD_HEIGHT);
current_tile=terrain[WORLD_TILE(x,y)];
if (!isroad(current_tile))
{
current_tile=terrain[WORLD_TILE(x,y)]=
roads_to_right[random(ROAD_LEADERS)];
direction=roadexit(current_tile, DIRECTION_LEFT);
}
else
{
roads_left++;
failed_roads++;
keepgoing=FALSE;
}
break;
}
/************************************************\
* PLACE SUBSEQUENT TILES AWAY FROM ENTRY POINT *
\************************************************/
while (keepgoing)
{
switch (direction)
{
/********/ case DIRECTION_UP: /* UP */
if (--y<0)
{
keepgoing=FALSE;
break;
}
current_tile=terrain[WORLD_TILE(x,y)];
if (!isroad(current_tile))
{
current_tile=terrain[WORLD_TILE(x,y)]=
roads_to_down[random(ROAD_LEADERS)];
direction=roadexit(current_tile, DIRECTION_UP);
}
else /* INTERSECTION OCCURS */
{
if (random(100)>=CHANCE_CROSSROAD &&
terrain[WORLD_TILE(x,y-1)]==EMPTY_TILE)
{
keepgoing=FALSE;
terrain[WORLD_TILE(x,y)]=makeintersection
(current_tile, DIRECTION_DOWN);
}
else /* CROSSROAD AND CONTINUE */
{
terrain[WORLD_TILE(x,y)]=makeintersection
(makeintersection(current_tile, DIRECTION_UP),
DIRECTION_DOWN); /* ADD BOTH RAMPS */
}
}
break;
/********/ case DIRECTION_DOWN: /* DOWN */
if (++y>=WORLD_HEIGHT)
{
keepgoing=FALSE;
break;
}
current_tile=terrain[WORLD_TILE(x,y)];
if (!isroad(current_tile))
{
current_tile=terrain[WORLD_TILE(x,y)]=
roads_to_up[random(ROAD_LEADERS)];
direction=roadexit(current_tile, DIRECTION_DOWN);
}
else /* INTERSECTION OCCURS */
{
if (random(100)>=CHANCE_CROSSROAD &&
terrain[WORLD_TILE(x,y+1)]==EMPTY_TILE)
{
keepgoing=FALSE;
terrain[WORLD_TILE(x,y)]=makeintersection
(current_tile, DIRECTION_UP);
}
else /* CROSSROAD AND CONTINUE */
{
terrain[WORLD_TILE(x,y)]=makeintersection
(makeintersection(current_tile, DIRECTION_DOWN),
DIRECTION_UP); /* ADD BOTH RAMPS */
}
}
break;
/********/ case DIRECTION_LEFT: /* LEFT */
if (--x<0)
{
keepgoing=FALSE;
break;
}
current_tile=terrain[WORLD_TILE(x,y)];
if (!isroad(current_tile))
{
current_tile=terrain[WORLD_TILE(x,y)]=
roads_to_right[random(ROAD_LEADERS)];
direction=roadexit(current_tile, DIRECTION_LEFT);
}
else /* INTERSECTION OCCURS */
{
if (random(100)>=CHANCE_CROSSROAD &&
terrain[WORLD_TILE(x-1,y)]==EMPTY_TILE)
{
keepgoing=FALSE;
terrain[WORLD_TILE(x,y)]=makeintersection
(current_tile, DIRECTION_RIGHT);
}
else /* CROSSROAD AND CONTINUE */
{
terrain[WORLD_TILE(x,y)]=makeintersection
(makeintersection(current_tile, DIRECTION_LEFT),
DIRECTION_RIGHT); /* ADD BOTH RAMPS */
}
}
break;
/********/ case DIRECTION_RIGHT: /* RIGHT */
if (++x>=WORLD_WIDTH)
{
keepgoing=FALSE;
break;
}
current_tile=terrain[WORLD_TILE(x,y)];
if (!isroad(current_tile))
{
current_tile=terrain[WORLD_TILE(x,y)]=
roads_to_left[random(ROAD_LEADERS)];
direction=roadexit(current_tile, DIRECTION_RIGHT);
}
else /* INTERSECTION OCCURS */
{
if (random(100)>=CHANCE_CROSSROAD &&
terrain[WORLD_TILE(x+1,y)]==EMPTY_TILE)
{
keepgoing=FALSE;
terrain[WORLD_TILE(x,y)]=makeintersection
(current_tile, DIRECTION_LEFT);
}
else /* CROSSROAD AND CONTINUE */
{
terrain[WORLD_TILE(x,y)]=makeintersection
(makeintersection(current_tile, DIRECTION_RIGHT),
DIRECTION_LEFT); /* ADD BOTH RAMPS */
}
}
break;
} /* "DIRECTION" HERE */
} /* STOP "KEEPGOING" HERE */
}
}
/*
*
* Returns the unspecified direction in an angled road.
*
*/
int roadexit (int road, int direction)
{
switch (direction)
{
case DIRECTION_UP: /* up */
if (road==ROAD_V) return DIRECTION_UP;
if (road==ROAD_UL) return DIRECTION_LEFT;
if (road==ROAD_UR) return DIRECTION_RIGHT;
break;
case DIRECTION_DOWN: /* down */
if (road==ROAD_V) return DIRECTION_DOWN;
if (road==ROAD_DL) return DIRECTION_LEFT;
if (road==ROAD_DR) return DIRECTION_RIGHT;
break;
case DIRECTION_LEFT: /* left */
if (road==ROAD_DR) return DIRECTION_UP;
if (road==ROAD_UR) return DIRECTION_DOWN;
if (road==ROAD_H) return DIRECTION_LEFT;
break;
case DIRECTION_RIGHT: /* right */
if (road==ROAD_DL) return DIRECTION_UP;
if (road==ROAD_UL) return DIRECTION_DOWN;
if (road==ROAD_H) return DIRECTION_RIGHT;
break;
}
fg_music ("A$");
return ERROR_TILE;
}
/*
*
* Adds a road (ramp) to the specified road, and returns the
* tile number of what the new road is made of.
*
*/
int makeintersection (int road, int ramp)
{
switch (road)
{
case ROAD_X: /* ┼ */
return ROAD_X;
case ROAD_V: /* │ */
if (ramp==DIRECTION_LEFT) return ROAD_TL;
if (ramp==DIRECTION_RIGHT) return ROAD_TR;
return ROAD_V;
case ROAD_H: /* ─ */
if (ramp==DIRECTION_UP) return ROAD_TU;
if (ramp==DIRECTION_DOWN) return ROAD_TD;
return ROAD_H;
case ROAD_UR: /* ┌ */
if (ramp==DIRECTION_UP) return ROAD_TR;
if (ramp==DIRECTION_LEFT) return ROAD_TD;
return ROAD_UR;
case ROAD_UL: /* ┐ */
if (ramp==DIRECTION_UP) return ROAD_TL;
if (ramp==DIRECTION_RIGHT) return ROAD_TD;
return ROAD_UL;
case ROAD_DR: /* └ */
if (ramp==DIRECTION_DOWN) return ROAD_TR;
if (ramp==DIRECTION_LEFT) return ROAD_TU;
return ROAD_DR;
case ROAD_DL: /* ┘ */
if (ramp==DIRECTION_DOWN) return ROAD_TL;
if (ramp==DIRECTION_RIGHT) return ROAD_TU;
return ROAD_DL;
case ROAD_TL: /* ┤ */
if (ramp==DIRECTION_RIGHT) return ROAD_X;
return ROAD_TL;
case ROAD_TR: /* ├ */
if (ramp==DIRECTION_LEFT) return ROAD_X;
return ROAD_TR;
case ROAD_TU: /* ┴ */
if (ramp==DIRECTION_DOWN) return ROAD_X;
return ROAD_TU;
case ROAD_TD: /* ┬ */
if (ramp==DIRECTION_UP) return ROAD_X;
return ROAD_TD;
}
fg_music ("A$");
return ERROR_TILE;
}
/*
AI USED IN ROAD FUNCTIONS:
pick random entry point on one of the four sides
place subsequent tiles with tendency to move from screen
place subsequent tiles with tendency use V or H pieces if just used
if hit existing tile, either
a) cross over road and continue, using X tile
b) terminate road with a T
repeat until MAX_ROADS complete
*/
/*
*
* Adds edges to places where grass and dirt meet.
* Called by init_background() to liven up background display.
*
*/
void add_dirt_edges (void)
{
register int x, y;
int tile;
/* ADD 90 DEGREE EDGES */
for (y=0; y<WORLD_HEIGHT; y++)
for (x=0; x<WORLD_WIDTH; x++)
if (isdirt(topography[WORLD_TILE(x,y)]))
{
tile=0; /* ADD UP BINARY TILE NUMBER */
if (y-1>=0) tile+=isgrass(topography[WORLD_TILE(x,y-1)]);
if (x+1<WORLD_WIDTH) tile+=isgrass(topography[WORLD_TILE(x+1,y)])*2;
if (y+1<WORLD_HEIGHT) tile+=isgrass(topography[WORLD_TILE(x,y+1)])*4;
if (x-1>=0) tile+=isgrass(topography[WORLD_TILE(x-1,y)])*8;
/* CONVERT BINARY TILE NUMBER TO ACTUAL */
switch (tile)
{
case 1: tile=DIRTEDGE_U; break;
case 2: tile=DIRTEDGE_R; break;
case 3: tile=DIRTEDGE_UR; break;
case 4: tile=DIRTEDGE_D; break;
case 5: tile=DIRTEDGE_UD; break;
case 6: tile=DIRTEDGE_RD; break;
case 7: tile=DIRTEDGE_URD; break;
case 8: tile=DIRTEDGE_L; break;
case 9: tile=DIRTEDGE_UL; break;
case 10: tile=DIRTEDGE_RL; break;
case 11: tile=DIRTEDGE_URL; break;
case 12: tile=DIRTEDGE_DL; break;
case 13: tile=DIRTEDGE_UDL; break;
case 14: tile=DIRTEDGE_RDL; break;
case 15: tile=DIRTEDGE_URDL; break;
case 0: tile=topography[WORLD_TILE(x,y)]; break; /* NO CHANGE */
}
topography[WORLD_TILE(x,y)]=tile; /* CHANGE TILE */
}
}